package main

import (
	"fmt"
	"os"
)

func fn1() {
	// 若干语句
	if true {
		return
	}
	// return // 仅仅返回，代表函数执行完成了，return 语句执行表示函数执行完成要收尾，栈帧消亡
	fmt.Println("我结束了")
	// return
}

func fn2() int {
	// return 1000
	// return -1
	a := 111 // 局部变量
	return 222 - a
}

func fn3() (r int) {
	// return 100
	// return //
	r = 200
	return r + 100
}

func fn4() (int, int) { // 多个返回值
	a, b := 1, -1
	a, b = b, a+b
	return a, b
}

func fn5() (x int, y bool) {
	// return 100, false
	x, y = 200, true
	return
}

// error 内建类型，接口类型，错误接口类型，接口类型零值 nil
func fn6() error {
	return nil
}
func fn7() (err error) {
	// return nil
	t, err := os.Open("/Users/yangzhenyu/Desktop/gitee/G/foundation/day8/func/main.go")
	fmt.Println(t)
	fmt.Println(err, "####") // err.String() 描述，有描述，有错误，错误就不是 nil
	return
}

func fn8() (err error) {
	if t, err := os.Open("o:/t.txt"); err != nil {
		fmt.Println(err, "%%%%%%%")
		fmt.Println(t)
		return err
	}
	return
}

func t1(nums ...int) {
	fmt.Printf("%T\n", nums)
	fmt.Printf("%v, %d, %d\n", nums, len(nums), cap(nums))
}

func t2(x, y int) { // 非 variadic，非可变，普通形参
	fmt.Println(x, y)
}

func t3(x, y int, nums ...int) {
	fmt.Println(x, y, "|||", nums)
	fmt.Printf("%p, %p, %d, %d\n", &nums, &nums[0], len(nums), cap(nums))
}

func f1(nums []int) {
	// nums局部变量，普通参数，只能接收[]int的一个实参
}

func f2(nums ...int) {

}

func main() {
	// func a() {} 不允许在一个函数内部使用 func 定义新函数
	// v := fn1() 没有返回值 不可以
	// fmt.Println(fn1()) 没有返回值 不可以
	// fn1() // 执行一次函数调用
	// fn1() // 两次调用是独立
	// fn2() // 只调用 不打印
	// fmt.Println(fn2())
	// t := fn3()
	// fmt.Println(t)

	// 多返回值，必须用对应个数的标识符来赋值，否则报错
	// fmt.Println(fn4())
	// fmt.Println(fn5()
	// fmt.Println(fn7(), "~~~~~~~~~~~~~~~~~~~")
	// t1(100, 200, 300, 400)
	// a := []int{1, 2, 3}
	// // t1(a1) // 不可以
	// t1(a...) // 切片解构

	// t2(1, 2)
	// t2([]int{100, 200}...) // go 不支持在普通参数上使用该语法

	// t3()
	// t3(1)
	t3(1, 2, 3)

	t3(1, 2, 3, 4)
	// t3([]int{1, 3, 5, 7}...)
	// t3(1, 3, 5, 7, []int{}...) // 对 nums 采用 2 中方式，不支持
	t := []int{3}
	fmt.Printf("%p, %p, %d, %d\n", &t, &t[0], len(t), cap(t))
	t3(1, 3, t...)
	s := []int{5, 7}
	fmt.Printf("%p, %p, %d, %d\n", &s, &s[0], len(s), cap(s))
	t3(1, 3, s...)

	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")

	f1([]int{})
	f2([]int{}...) // 切片传递
	f2()
	f2(1, 2, 3)
	fmt.Println([]int{1})
	// fmt.Println([]int{1}...) 不可以
	x := []any{1, 3}
	// 对[]any{1, 3} []int{1, 3} 做遍历
	// 对 for i, v := range a {}
	fmt.Println(x)    // 1个元素按照位置提供给 a 这个[]any{t}
	fmt.Println(x...) // 什么意思？共用底层数组，a 和t 共用底层数组[]any{1, 3}

}
